package proxy;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Proxyer {
	interface IHello {
		void sayHello2();

		void sayHello1() throws InterruptedException;

		void editHello3(int key,String ss);
	}

	static class Hello implements IHello {
		public Hello() {
			System.out.println("hello world0");
		}
		public Hello(int i) {
			System.out.println("hello worldi");
		}

		@Override
		public void sayHello2() {
			System.out.println("hello world");
		}				

		@Override
		public void sayHello1() throws InterruptedException {
//				Thread.sleep(3000);
			System.out.println("hello world1");
			// TODO Auto-generated method stub

		}

		@Override
		public void editHello3(int key,String ss) {
			System.out.println("edit world1:"+key+", ss:"+ss);
			// TODO Auto-generated method stub

		}
	}

	/*static class DynamicProxy implements InvocationHandler{*/
	static class DynamicProxy {
		public DynamicProxy() {
			System.out.println("initializing dynamicProxy...");
		}

		Object originalObj;

		Object bind(final Object originalObj) {
			this.originalObj = originalObj;
			return Proxy.newProxyInstance(originalObj.getClass().getClassLoader(),
					originalObj.getClass().getInterfaces(), new InvocationHandler() {
						public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
							method.invoke(originalObj, args);
							Pattern pattern = Pattern.compile("^(edit)");
							Matcher matcher = pattern.matcher(method.getName());
							if (matcher.find()) {
								System.out.println("method:" + method.getName());
								System.out.println("invoking...");
							}
							return null;
						}
					});
		}

		/*@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			System.out.println("welcome");
			return method.invoke(originalObj, args);
		}*/
	}

	public static void main(String[] args) {
		IHello hello = (IHello) new DynamicProxy().bind(new Hello());
		try {
			hello.sayHello1();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//Hello hello2 = new Hello();
//		hello.editHello3(5,"hg");
//		Class class1 = hello.getClass();
//		Field[] fields = class1.getDeclaredFields();
//		for (Field field : fields) {
//			field.setAccessible(true);
//			try {
//				System.out.println(field.getName());
//				System.out.println(field.get(hello));
//			} catch (IllegalArgumentException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			} catch (IllegalAccessException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
//		System.out.println("---------------");
//		Method[] methods = class1.getDeclaredMethods();
//		for (Method method : methods) {
//			method.setAccessible(true);
//			try {
//				System.out.println(method.toString());
//			} catch (IllegalArgumentException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
		
		/*IHello hello3 = (IHello) java.lang.reflect.Proxy.newProxyInstance(hello2.getClass().getClassLoader(),hello2.getClass().getInterfaces() , new InvocationHandler() {  
			  
		public Object invoke(Object proxy, Method method, Object[] args)  
		                                                                throws Throwable {  
		    System.out.println("method:" + method.getName());  
		    System.out.println("Method before...");  
		    Object result = method.invoke(hello2, args);  
		    System.out.println("Method after...");  
		    return result;  
			//return null;
		}  
		});*/
		//hello3.sayHello2();

	}
}
